package com.example.demo.exception;

import com.example.demo.common.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.Map;

/**
 * 全局异常处理器
 * 统一处理应用中的各种异常
 */
@RestControllerAdvice
public class GlobalExceptionHandler {
    
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    
    /**
     * 处理业务异常
     * @param e 业务异常
     * @return 统一响应结果
     */
    @ExceptionHandler(BusinessException.class)
    public Result<Object> handleBusinessException(BusinessException e) {
        log.warn("业务异常：{}", e.getMessage());
        Integer code = e.getCode() != null ? e.getCode() : 1001;
        return Result.error(code, e.getMessage());
    }
    
    /**
     * 处理参数验证异常
     * @param e 参数验证异常
     * @return 统一响应结果
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<Object> handleValidationException(MethodArgumentNotValidException e) {
        log.warn("参数验证异常：{}", e.getMessage());
        
        BindingResult bindingResult = e.getBindingResult();
        Map<String, String> errors = new HashMap<>();
        
        bindingResult.getFieldErrors().forEach(error -> {
            errors.put(error.getField(), error.getDefaultMessage());
        });
        
        return Result.error(1002, "参数验证失败", errors);
    }
    
    /**
     * 处理参数异常
     * @param e 参数异常
     * @return 统一响应结果
     */
    @ExceptionHandler(IllegalArgumentException.class)
    public Result<Object> handleIllegalArgumentException(IllegalArgumentException e) {
        log.warn("参数异常：{}", e.getMessage());
        return Result.error(1003, "参数错误：" + e.getMessage());
    }
    
    /**
     * 处理空指针异常
     * @param e 空指针异常
     * @return 统一响应结果
     */
    @ExceptionHandler(NullPointerException.class)
    public Result<Object> handleNullPointerException(NullPointerException e) {
        log.error("空指针异常：", e);
        return Result.error(1004, "系统内部错误");
    }
    
    /**
     * 处理运行时异常
     * @param e 运行时异常
     * @return 统一响应结果
     */
    @ExceptionHandler(RuntimeException.class)
    public Result<Object> handleRuntimeException(RuntimeException e) {
        log.error("运行时异常：", e);
        return Result.error(1005, "系统内部错误");
    }
    
    /**
     * 处理资源未找到异常（如favicon.ico）
     * @param e 资源未找到异常
     * @return 统一响应结果
     */
    @ExceptionHandler(org.springframework.web.servlet.resource.NoResourceFoundException.class)
    public Result<Object> handleNoResourceFoundException(org.springframework.web.servlet.resource.NoResourceFoundException e) {
        // 对于favicon.ico等静态资源请求，只记录debug级别日志
        String resourcePath = e.getResourcePath();
        if (resourcePath != null && (resourcePath.contains("favicon.ico") || resourcePath.contains(".ico"))) {
            log.debug("静态资源未找到：{}", resourcePath);
            return Result.error(404, "资源未找到");
        }
        
        log.warn("静态资源未找到：{}", resourcePath);
        return Result.error(404, "请求的资源不存在");
    }
    
    /**
     * 处理其他异常
     * @param e 异常
     * @return 统一响应结果
     */
    @ExceptionHandler(Exception.class)
    public Result<Object> handleException(Exception e) {
        log.error("系统异常：", e);
        return Result.error(1000, "系统繁忙，请稍后重试");
    }
}